/*
package com.ruiyi.subway.utils;

import com.google.common.collect.Lists;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.yuancore.common.gson.Gson;
import com.yuancore.vcs.common.enums.EConditionType;
import com.yuancore.vcs.common.enums.ExceptionCode;
import com.yuancore.vcs.common.exception.VcsBusinessException;
import com.yuancore.vcs.dto.RecodeSearchDto;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.search.MatchQuery;

import java.util.List;
import java.util.Map;

*/
/**
 * Created by lw on 2017/8/23.
 *//*

@Slf4j
public class QueryBuilderUtils {
    private final static Gson GSON = new Gson();

    private final static String KEY_TO = "to";
    private final static String KEY_FROM = "from";

    */
/**
     * 根据限定条件和查询条件解析出查询条件，限定条件的格式如下：<br />
     * <pre>
     * {
     * "product_id": {
     * "$eq": "aac240b0-b48c-4b67-8256-086f9b19ac8e"
     * },
     * "title": {
     * "$pre": "测试标题"
     * },
     * "data": {
     * "$gte": "2017-08-01",
     * "$lt": "2017-08-23"
     * },
     * "uploader": {
     * "$suf": "test"
     * }
     * }
     * 目前支持的逻辑运算介绍：(不通过$or连接的属性间，默认是$and与)
     * 1. $or：或
     * 2. $eq：等于
     * 3. $pre：以给定的字符开始
     * 4. $suf：以给定的字符结束
     * 5. $gte：大于等于
     * 6. $gt：大于
     * 7. $lte：小于等于
     * 8. $lt：小于
     * </pre>
     *
     * @param json      限定条件
     * @param searchDto 查询条件
     * @return
     * @throws VcsBusinessException
     *//*

    public static BoolQueryBuilder parseBoolQuery(JsonObject json, RecodeSearchDto searchDto) throws VcsBusinessException {
        List<String> usedKeys = Lists.newArrayList();
        BoolQueryBuilder query = QueryBuilders.boolQuery();

        // 1. 对限定的数据范围进行解析
        if (json != null && !json.isJsonNull()) {
            try {
                for (Map.Entry<String, JsonElement> entry : json.entrySet()) {
                    usedKeys.add(entry.getKey());
                    JsonElement ele = entry.getValue();

                    QueryBuilder queryBuilder;
                    if (ele.isJsonPrimitive()) {
                        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery(entry.getKey(), "\"" + ele.getAsJsonPrimitive().getAsString() + "\"");
                        matchQueryBuilder.type(MatchQuery.Type.PHRASE_PREFIX);
                        queryBuilder = matchQueryBuilder;
                    } else {
                        JsonObject conditionJson = ele.getAsJsonObject();
                        List<Map.Entry<String, JsonElement>> conditions = Lists.newArrayList(conditionJson.entrySet().iterator());
                        if (conditions.size() == 1) {
                            queryBuilder = genQuery(entry.getKey(), conditions.get(0).getKey(), conditions.get(0).getValue().getAsString(), searchDto);
                        } else if (conditions.size() == 2) {
                            queryBuilder = genRangeQuery(entry.getKey(), conditionJson, searchDto);
                        } else {
                            throw VcsBusinessException.buildException(ExceptionCode.PARAM_ILLEGAL);
                        }
                    }

                    query.must(queryBuilder);
                }
            } catch (Exception e) {
                throw new VcsBusinessException(e);
            }
        }

        // 2.1 解析剩下的查询条件，合并到查询构造器中
        if (searchDto.getParams() != null) {
            for (String key : searchDto.getParams().keySet()) {
                if (!usedKeys.contains(key)) {
                    MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery(key, "\"" + searchDto.getParams().get(key) + "\"");
                    matchQueryBuilder.type(MatchQuery.Type.PHRASE_PREFIX);
                    query.must(matchQueryBuilder);
                }
            }
        }

        // 2.2 解析剩下的范围查询条件，合并到查询构造器中
        if (searchDto.getDate() != null) {
            for (String key : searchDto.getDate().keySet()) {
                if (!usedKeys.contains(key)) {
                    Map<String, String> d = searchDto.getDate().get(key);
                    QueryBuilder q = QueryBuilders.rangeQuery(key).from(d.get(KEY_FROM)).to(d.get(KEY_TO));
                    query.must(q);
                }
            }
        }

        return query;
    }

    */
/**
     * 构造简单的查询器
     *
     * @param property  字段名
     * @param op        值操作
     * @param value     模板值
     * @param searchDto 查询条件
     * @return
     * @throws VcsBusinessException
     *//*

    private static QueryBuilder genQuery(String property, String op, String value, RecodeSearchDto searchDto) throws VcsBusinessException {
        EConditionType type = GSON.fromJson(op.toUpperCase(), EConditionType.class);
        switch (type) {
            case $EQ:
                MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery(property, "\"" + value + "\"");
                matchQueryBuilder.type(MatchQuery.Type.PHRASE_PREFIX);
                return matchQueryBuilder;
            case $PRE:
                return QueryBuilders.prefixQuery(property, value);
            case $SUF:
                MatchQueryBuilder mq;
                if (searchDto != null && searchDto.getParams() != null && searchDto.getParams().containsKey(property)) {
                    mq = QueryBuilders.matchQuery(property, "\"" + searchDto.getParams().get(property) + value + "\"");
                } else {
                    mq = QueryBuilders.matchQuery(property, "\"" + value + "\"");
                }
                mq.type(MatchQuery.Type.PHRASE_PREFIX);
                return mq;
            default:
                throw VcsBusinessException.buildException(ExceptionCode.PARAM_ILLEGAL);
        }
    }

    */
/**
     * 解析范围条件，将限定的范围条件与本次查询的范围条件进行比对，选择范围最小的作为最终的查询条件
     *
     * @param property  查询字段
     * @param obj       限定的范围条件
     * @param searchDto 查询的范围条件
     * @return
     * @throws VcsBusinessException
     *//*

    private static QueryBuilder genRangeQuery(String property, JsonObject obj, RecodeSearchDto searchDto) throws VcsBusinessException {
        JsonPrimitive from = obj.getAsJsonPrimitive(EConditionType.$GT.toString());
        from = from == null ? obj.getAsJsonPrimitive(EConditionType.$GTE.toString()) : from;
        JsonPrimitive to = obj.getAsJsonPrimitive(EConditionType.$LT.toString());
        to = to == null ? obj.getAsJsonPrimitive(EConditionType.$LTE.toString()) : to;

        if (from == null && to == null) {
            throw VcsBusinessException.buildException(ExceptionCode.PARAM_ILLEGAL);
        }

        String fromStr = from.getAsString(), toStr = to.getAsString();
        QueryBuilder rangeQuery;

        // 解析实际的查询范围条件，与限定的范围条件进行比对，最终得到范围最小的查询条件
        Map<String, String> rangeConditions;
        if (searchDto != null && searchDto.getDate() != null) {
            Map<String, Map<String, String>> date = searchDto.getDate();
            rangeConditions = date.get(property);
            if (rangeConditions != null && !rangeConditions.isEmpty()) {
                if (rangeConditions.containsKey(KEY_FROM)) {
                    fromStr = fromStr.compareTo(rangeConditions.get(KEY_FROM)) <= 0 ? rangeConditions.get(KEY_FROM) : fromStr;
                }

                if (rangeConditions.containsKey(KEY_TO)) {
                    toStr = toStr.compareTo(rangeConditions.get(KEY_TO)) <= 0 ? toStr : rangeConditions.get(KEY_TO);
                }
            }
        }

        if (from == null) {
            rangeQuery = QueryBuilders.rangeQuery(property).to(toStr);
        } else if (to == null) {
            rangeQuery = QueryBuilders.rangeQuery(property).from(fromStr);
        } else {
            rangeQuery = QueryBuilders.rangeQuery(property).from(fromStr).to(toStr);
        }

        return rangeQuery;
    }

    public static void main(String[] args) throws VcsBusinessException {
        String bson = "{\n" +
                "    \"product_id\": {\n" +
                "        \"$EQ\": \"aac240b0-b48c-4b67-8256-086f9b19ac8e\"\n" +
                "    },\n" +
                "    \"title\": {\n" +
                "        \"$PRE\": \"测试标题\"\n" +
                "    },\n" +
                "    \"date\": {\n" +
                "        \"$GTE\": \"2017-08-01\",\n" +
                "        \"$LT\": \"2017-08-23\"\n" +
                "    },\n" +
                "    \"uploader\": {\n" +
                "        \"$SUF\": \"test\"\n" +
                "    }\n" +
                "}";

//        JsonObject jsonObject = GSON.fromJson(bson, JsonObject.class);
//        RecodeSearchDto searchDto = new RecodeSearchDto();
//        Map<String, String> params = Maps.newHashMap();
//        params.put("title", "hello");
//        searchDto.setParams(params);
//
//        Map<String, Map<String, String>> dateMap = Maps.newHashMap();
//        Map<String, String> rangeMap = Maps.newHashMap();
//        rangeMap.put("from", "2017-08-15");
//        rangeMap.put("to", "2017-08-26");
//        dateMap.put("date", rangeMap);
//
//        searchDto.setDate(dateMap);
//
//        BoolQueryBuilder query = QueryBuilderUtils.parseBoolQuery(jsonObject, searchDto);
//        log.info("query: {}", query);
    }
}
*/
